package http.orig;


import http.exception.HttpException ;
import http.tool.Tools ;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;

/**
 * desc:
 * user: Alec Fan
 * date: 2016/9/30
 * time: 17:55
 */
public abstract class Request<T extends Request> {
    protected final HttpURLConnection connection;
    private boolean connected;
    protected final String url;

    public Request(String url, int connectTimeout, int readTimeout) {
        try {
            this.url = url;
            if(Tools.isHTTPs(url)) {
                this.connection = (HttpsURLConnection) (new URL(url)).openConnection();
                SSL.addSSL((HttpsURLConnection)this.connection) ;
            }
            else
                this.connection = (HttpURLConnection) (new URL(url)).openConnection();
            this.connection.setConnectTimeout(connectTimeout);
            this.connection.setReadTimeout(readTimeout);
        } catch (Exception var5) {
            throw new HttpException("Failed URL: " + url, var5);
        }
    }
    
    
    public Request(String url, int connectTimeout, int readTimeout, String keypath, String keypwd,String keyType, String trustpath, String trustpwd,String trustType) {
        try {
            this.url = url;
            if(Tools.isHTTPs(url)) {
                this.connection = (HttpsURLConnection) (new URL(url)).openConnection();
                SSL.addSSL((HttpsURLConnection)this.connection, keypath, keypwd, keyType, trustpath, trustpwd, trustType, "SSL") ;
            }
            else
                this.connection = (HttpURLConnection) (new URL(url)).openConnection();
            this.connection.setConnectTimeout(connectTimeout);
            this.connection.setReadTimeout(readTimeout);
        } catch (Exception var5) {
            throw new HttpException("Failed URL: " + url, var5);
        }
    }
    

    public Request<T> header(String name, String value) {
        this.connection.setRequestProperty(name, value);
        return this;
    }

    public InputStream getInputStream() {
        try {
            return this.connection.getInputStream();
        } catch (SocketTimeoutException var2) {
            throw new HttpException("Failed URL: " + this.url + ", waited for: " + this.connection.getConnectTimeout() + " milliseconds", var2);
        } catch (Exception var3) {
            throw new HttpException("Failed URL: " + this.url, var3);
        }
    }

    public Map<String, List<String>> headers() {
        this.connect();
        return this.connection.getHeaderFields();
    }

    public int responseCode() {
        try {
            this.connect();
            return this.connection.getResponseCode();
        } catch (Exception var2) {
            throw new HttpException("Failed URL: " + this.url, var2);
        }
    }

    public String responseMessage() {
        try {
            this.connect();
            return this.connection.getResponseMessage();
        } catch (Exception var2) {
            throw new HttpException("Failed URL: " + this.url, var2);
        }
    }

    public byte[] bytes() {
        this.connect();
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];

        try {
            InputStream e = this.connection.getInputStream();

            int count;
            while ((count = e.read(bytes)) != -1) {
                bout.write(bytes, 0, count);
            }
        } catch (Exception var5) {
            throw new HttpException("Failed URL: " + this.url, var5);
        }

        this.dispose();
        return bout.toByteArray();
    }

    public String text() {
        try {
            this.connect();
            String e = this.responseCode() >= 400 ? Tools.read(this.connection.getErrorStream()) : Tools.read(this.connection.getInputStream());
            this.dispose();
            return e;
        } catch (IOException var2) {
            throw new HttpException("Failed URL: " + this.url, var2);
        }
    }

    public String text(String encoding) {
        try {
            this.connect();
            String e = this.responseCode() >= 400 ? Tools.read(this.connection.getErrorStream()) : Tools.read(this.connection.getInputStream(), encoding);
            this.dispose();
            return e;
        } catch (IOException var3) {
            throw new HttpException("Failed URL: " + this.url, var3);
        }
    }

    public void dispose() {
        byte[] bytes = new byte[1024];

        try {
            InputStream ignore = this.connection.getInputStream();
            if (ignore != null) {
                while (true) {
                    if (ignore.read(bytes) <= 0) {
                        ignore.close();
                        break;
                    }
                }
            }
        } catch (Exception var5) {
            try {
                InputStream ignoreToo = this.connection.getErrorStream();
                if (ignoreToo != null) {
                    while (true) {
                        if (ignoreToo.read(bytes) <= 0) {
                            ignoreToo.close();
                            break;
                        }
                    }
                }
            } catch (IOException var4) {
                ;
            }
        }

    }

    protected Request connect() {
        if (!this.connected) {
            Request t = this.doConnect();
            this.connected = true;
            return t;
        } else {
            return this;
        }
    }

    protected abstract T doConnect();

    public Request<T> basic(String user, String password) {
        this.connection.setRequestProperty("Authorization", "Basic " + Tools.toBase64((user + ":" + password).getBytes()));
        return this;
    }
    
}
